//#include <DetectionBasedTracker_jni.h>
//#include <opencv2/core.hpp>
//#include <opencv2/objdetect.hpp>
//
//#include <string>
//#include <vector>
//
//#include <android/log.h>
//
//#define LOG_TAG "FaceDetection/DetectionBasedTracker"
//#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
//
//using namespace std;
//using namespace cv;
//
//inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat)
//{
//    mat = Mat(v_rect, true);
//}
//
//class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
//{
//public:
//    CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
//            IDetector(),
//            Detector(detector)
//    {
//        LOGD("CascadeDetectorAdapter::Detect::Detect");
//        CV_Assert(detector);
//    }
//
//    void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
//    {
//        LOGD("CascadeDetectorAdapter::Detect: begin");
//        LOGD("CascadeDetectorAdapter::Detect: scaleFactor=%.2f, minNeighbours=%d, minObjSize=(%dx%d), maxObjSize=(%dx%d)", scaleFactor, minNeighbours, minObjSize.width, minObjSize.height, maxObjSize.width, maxObjSize.height);
//        Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);
//        LOGD("CascadeDetectorAdapter::Detect: end");
//    }
//
//    virtual ~CascadeDetectorAdapter()
//    {
//        LOGD("CascadeDetectorAdapter::Detect::~Detect");
//    }
//
//private:
//    CascadeDetectorAdapter();
//    cv::Ptr<cv::CascadeClassifier> Detector;
//};
//
//struct DetectorAgregator
//{
//    cv::Ptr<CascadeDetectorAdapter> mainDetector;
//    cv::Ptr<CascadeDetectorAdapter> trackingDetector;
//
//    cv::Ptr<DetectionBasedTracker> tracker;
//    DetectorAgregator(cv::Ptr<CascadeDetectorAdapter>& _mainDetector, cv::Ptr<CascadeDetectorAdapter>& _trackingDetector):
//            mainDetector(_mainDetector),
//            trackingDetector(_trackingDetector)
//    {
//        CV_Assert(_mainDetector);
//        CV_Assert(_trackingDetector);
//
//        DetectionBasedTracker::Parameters DetectorParams;
//        tracker = makePtr<DetectionBasedTracker>(mainDetector, trackingDetector, DetectorParams);
//    }
//};
//
//JNIEXPORT jlong JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeCreateObject
//(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter");
//    const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL);
//    string stdFileName(jnamestr);
//    jlong result = 0;
//
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject");
//
//    try
//    {
//        cv::Ptr<CascadeDetectorAdapter> mainDetector = makePtr<CascadeDetectorAdapter>(
//            makePtr<CascadeClassifier>(stdFileName));
//        cv::Ptr<CascadeDetectorAdapter> trackingDetector = makePtr<CascadeDetectorAdapter>(
//            makePtr<CascadeClassifier>(stdFileName));
//        result = (jlong)new DetectorAgregator(mainDetector, trackingDetector);
//        if (faceSize > 0)
//        {
//            mainDetector->setMinObjectSize(Size(faceSize, faceSize));
//            //trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
//        }
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//        catch (...)
//        {
//        LOGD("nativeCreateObject caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeCreateObject()");
//        return 0;
//    }
//
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit");
//    return result;
//}
//
//JNIEXPORT void JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeDestroyObject
//(JNIEnv * jenv, jclass, jlong thiz)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject");
//
//    try
//    {
//        if(thiz != 0)
//        {
//            ((DetectorAgregator*)thiz)->tracker->stop();
//            delete (DetectorAgregator*)thiz;
//        }
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeestroyObject caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//    catch (...)
//    {
//        LOGD("nativeDestroyObject caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeDestroyObject()");
//    }
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit");
//}
//
//JNIEXPORT void JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeStart
//(JNIEnv * jenv, jclass, jlong thiz)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart");
//
//    try
//    {
//        ((DetectorAgregator*)thiz)->tracker->run();
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeStart caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//    catch (...)
//    {
//        LOGD("nativeStart caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStart()");
//    }
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit");
//}
//
//JNIEXPORT void JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeStop
//(JNIEnv * jenv, jclass, jlong thiz)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop");
//
//    try
//    {
//        ((DetectorAgregator*)thiz)->tracker->stop();
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeStop caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//    catch (...)
//    {
//        LOGD("nativeStop caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeStop()");
//    }
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit");
//}
//
//JNIEXPORT void JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeSetFaceSize
//(JNIEnv * jenv, jclass, jlong thiz, jint faceSize)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- BEGIN");
//
//    try
//    {
//        if (faceSize > 0)
//        {
//            ((DetectorAgregator*)thiz)->mainDetector->setMinObjectSize(Size(faceSize, faceSize));
//            //((DetectorAgregator*)thiz)->trackingDetector->setMinObjectSize(Size(faceSize, faceSize));
//        }
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeStop caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//    catch (...)
//    {
//        LOGD("nativeSetFaceSize caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code of DetectionBasedTracker.nativeSetFaceSize()");
//    }
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- END");
//}
//
//
//JNIEXPORT void JNICALL Java_demo_rayootech_com_cvcheck_DetectionBasedTracker_nativeDetect
//(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces)
//{
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect");
//
//    try
//    {
//        vector<Rect> RectFaces;
//        ((DetectorAgregator*)thiz)->tracker->process(*((Mat*)imageGray));
//        ((DetectorAgregator*)thiz)->tracker->getObjects(RectFaces);
//        *((Mat*)faces) = Mat(RectFaces, true);
//    }
//    catch(cv::Exception& e)
//    {
//        LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
//        jclass je = jenv->FindClass("org/opencv/core/CvException");
//        if(!je)
//            je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, e.what());
//    }
//    catch (...)
//    {
//        LOGD("nativeDetect caught unknown exception");
//        jclass je = jenv->FindClass("java/lang/Exception");
//        jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()");
//    }
//    LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect END");
//}
//
//
//JNIEXPORT jintArray JNICALL Java_demo_rayootech_com_cvcheck_LibFuns_ImgToGray(
//        JNIEnv* env, jobject obj, jintArray buf, int w, int h) {
//
//    jint *cbuf;
//    cbuf = env->GetIntArrayElements(buf, false);
//
//    if (cbuf == NULL) {
//        return 0; /* exception occurred */
//    }
//
//    int alpha = 0xFF << 24;
//    for (int i = 0; i < h; i++) {
//        for (int j = 0; j < w; j++) {
//            // 获得像素的颜色
//            int color = cbuf[w * i + j];
//            int red = ((color & 0x00FF0000) >> 16);
//            int green = ((color & 0x0000FF00) >> 8);
//            int blue = color & 0x000000FF;
//            color = (red + green + blue) / 3;
//            color = alpha | (color << 16) | (color << 8) | color;
//            cbuf[w * i + j] = color;
//        }
//    }
//
//    int size=w * h;
//
//    jintArray result = env->NewIntArray(size);
//    env->SetIntArrayRegion(result, 0, size, cbuf);
//    env->ReleaseIntArrayElements(buf, cbuf, 0);
//    return result;
//}
